<template>
    <div style="height:100%">
        <a-input-search style="margin-bottom: 8px" v-model="searchValue" placeholder="请输入查询内容" @change="onTreeSearchChange" />
        <div>
            <div class="hh-scroll-hover" :style="{height:height}">
              <div>
                <a-tree
                  :showLine="showLine"
                  :showIcon="showIcon"
                  :multiple="multiple"
                  :blockNode="blockNode"
                  :selectable="selectable"
                  :replaceFields="replaceFields"
                  :checkable="checkable"
                  @expand="onExpand"
                  :expandedKeys="theExpandedKeys"
                  :selectedKeys="theSelectedKeys"
                  :autoExpandParent="theAutoExpandParent"
                  :treeData="treeList"
                  :draggable="draggable"
                  @dragenter="onDragEnter"
                  @dragleave="onDragleave"
                  @dragend="onDragend"
                  @drop="onDrop"
                  @dragover="onDragover"
                  @dragstart="onDragstart"
                  @load="onLoad"
                  @rightClick="onRightClick"
                  @select="onTreeSelect"
                >
                  <template slot="title" slot-scope="{title}">
                    <span v-if="title.indexOf(searchValue) > -1">
                      {{ title.substr(0, title.indexOf(searchValue)) }}
                      <span class="search-tree-color">{{ searchValue }}</span>
                      {{ title.substr(title.indexOf(searchValue) + searchValue.length) }}
                    </span>
                    <span v-else>{{ title }}</span>
                  </template>
                </a-tree>
              </div>
            </div>
        </div>
    </div>
</template>
<script>
import { loop, loopParentKey } from '@/utils/util'
export default {
  name: 'ZhTree',
  props: {
    //是否展示连接线
    showLine: {
      type: Boolean,
      default: true
    },
    //高度
    height:{
      type: String,
      default: "420px"
    },
    //是否展示 TreeNode title 前的图标，没有默认样式，如设置为 true，需要自行定义图标相关样式
    showIcon: {
      type: Boolean,
      default: false
    },
    //支持点选多个节点（节点本身）
    multiple: {
      type: Boolean,
      default: false
    },
    //设置节点可拖拽
    draggable: {
      type: Boolean,
      default: true
    },
    //将树禁用
    disabled: {
      type: Boolean,
      default: false
    },
    //是否节点占据一行
    blockNode: {
      type: Boolean,
      default: false
    },
    //是否可选中
    selectable: {
      type: Boolean,
      default: true
    },
    //是否自动展开父节点
    autoExpandParent: {
      type: Boolean,
      default: false
    },
    //节点前添加 Checkbox 复选框
    checkable: {
      type: Boolean,
      default: false
    },
    //替换 treeNode 中 title,key,children 字段为 treeData 中对应的字段
    replaceFields:{
      type: Object,
      default: function() {
        return {children:'children', title:'title', key:'key',value:'title',parentKey:'parentId' };
      }
    },
    //返回数据字段配置
    resultFields:{
      type: Object,
      default: function() {
        return {treeList:'treeList',expandedKeys:'expandedKeys',selectedKeys:'selectedKeys'};
      }
    },
    //treeNodes 数据，如果设置则不需要手动构造 TreeNode 节点（key 在整个树范围内唯一）
    treeData: {
      type: Array,
      default: function() {
        return null;
      }
    },
    //查询url
    url: {
      type: String,
      default: null
    },
    //移动节点url
    moveUrl: {
      type: String,
      default: null
    },
    //（受控）展开指定的树节点
    expandedKeys: {
      type: Array,
      default: function() {
        return [];
      }
    },
    selectedKeys: {
      type: Array,
      default: function() {
        return [];
      }
    },
    //查询提交到后台字段
    searchField:{
        type: String,
        default:"searchText"
    },
  },
  data () {
    return { 
        theAutoExpandParent:this.autoExpandParent,
        theExpandedKeys:this.expandedKeys,
        theSelectedKeys:this.selectedKeys,
        searchValue:null,
        treeList:[]
    }
  },
  watch: {
    autoExpandParent(val){
        this.theAutoExpandParent=val
    },
    expandedKeys(val){
        this.theExpandedKeys=val
    },
    selectedKeys(val){
        this.treeList=val
    },
    treeData(val){
        this.theSelectedKeys=val
    }
  },
  computed:{
	nodeKey(){
		return this.replaceFields.key;
	},
	nodeTitle(){
		return this.replaceFields.title;
    },
    nodeValue(){
		return this.replaceFields.value;
    },
    nodeParentKey(){
		return this.replaceFields.parentKey;
    }
  },
  created () {
      this.query()
  },
  methods: { 
    query(){
      if(this.url){
        const params = {}
        params[this.searchField] = this.searchValue
        let vim =this
        setTimeout(() => {
            this.$http.post(this.url,params).then((res) => {
                let result=res.result
                const list = result[vim.resultFields.treeList]
                if(list){
                    list.forEach((item) => {
                        item.isLeaf = item.leaf
                    })
                }
                this.treeList = list
                this.theExpandedKeys = result[vim.resultFields.expandedKeys]||[]
                let selectedKeys=result[vim.resultFields.selectedKeys]
                this.theSelectedKeys=selectedKeys||[]
            }).catch(() => {
            })
        }, 50)
      }
      
    },
    refresh(list,expandedKeys,selectedKeys){
        if(list){
            this.setList(list,expandedKeys,selectedKeys)
        }else{
            this.query()
        }
    },
    onExpand (expandedKeys) {
        this.theExpandedKeys = expandedKeys
        this.theAutoExpandParent = false
    },
    //设置数据
    setList (list,expandedKeys,selectedKeys) {
      this.treeList=list
      this.theExpandedKeys=expandedKeys
      this.theSelectedKeys=selectedKeys
    },
    onDragEnter (info) {
      this.$emit('dragenter',info )
    },
    onDragend (info) {
      this.$emit('dragend',info )
    },
    onDrop (info) {
      const dropKey = info.node.eventKey
      const dragKey = info.dragNode.eventKey
      const dropPos = info.node.pos.split('-')
      const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1])
      const params = {}
      params.dropKey = dropKey
      params.dragKey = dragKey
      params.dropPosition = dropPosition
      if(this.moveUrl){
        setTimeout(() => {
            this.$http.post(this.moveUrl,params).then((res) => {
            const data = [...this.treeList]
            // Find dragObject
            let dragObj
            loop(data, dragKey, (item, index, arr) => {
                arr.splice(index, 1)
                dragObj = item
            })
            if (!info.dropToGap) {
                // Drop on the content
                loop(data, dropKey, item => {
                item.children = item.children || []
                // where to insert 示例添加到尾部，可以是随意位置
                item.children.push(dragObj)
                })
            } else if (
                (info.node.children || []).length > 0 && // Has children
                info.node.expanded && // Is expanded
                dropPosition === 1 // On the bottom gap
            ) {
                loop(data, dropKey, item => {
                item.children = item.children || []
                // where to insert 添加到第一行
                item.children.unshift(dragObj)
                })
            } else {
                let ar
                let i
                loop(data, dropKey, (item, index, arr) => {
                ar = arr
                i = index
                })
                if (dropPosition === -1) {
                ar.splice(i, 0, dragObj)
                } else {
                ar.splice(i + 1, 0, dragObj)
                }
            }
            this.treeList = data
            this.$emit('drop',res.result )
            }).catch(() => {
            })
        }, 50)
      }else{
        this.$emit('drop',params)
      }
      
    },
    // 选中树节点
    onTreeSelect (selectedKeys,e) {
      this.theSelectedKeys = selectedKeys
      this.$emit('select',selectedKeys,e)
    },
    onDragleave(info){
        this.$emit('dragleave',info)
    },
    onDragover(info){
        this.$emit('dragover',info)
    },
    onDragstart(info){
        this.$emit('dragstart',info)
    },
    onLoad(info){
        this.$emit('load',info)
    },
    onRightClick(info){
        this.$emit('rightClick',info)
    },
    onTreeSearchChange (e) {
      const value = e.target.value
      if (value) {
        const data = [...this.treeList]
        const expandedKeys = []
        loopParentKey(data, value, expandedKeys)
        this.theExpandedKeys = expandedKeys
        this.searchValue = value
        this.theAutoExpandParent = true
      }
    },
    //更新树  type='1' 同级新增 type='2'子级新增 type='3'更新 type='4' 删除 
    updateTree (treeData,type) {
        if(!type){
            //为空默认按修改处理
            type='3'
        }
        const data = [...this.treeList]
        const dragKey = treeData.dragKey
        const dropKey = treeData.dropKey
        const dragObj = {}
        dragObj.key = treeData[this.nodeKey]
        dragObj.title = treeData[this.nodeTitle]
        dragObj.value = treeData[this.nodeValue]
        dragObj.parentKey = treeData[this.nodeParentKey]
        dragObj.scopedSlots = { title: 'title' }
        if (type === '1') {
            // 同级新增
            if(dragKey){
                let ar
                let i
                loop(data, dragKey, (item, index, arr) => {
                    ar = arr
                    i = index
                })
                ar.splice(i, 0, dragObj)
            }else{
                data.push(dragObj)
            }
           
        } else if (type === '2') {
            // 子级新增
            loop(data, dropKey, item => {
                item.children = item.children || []
                if (!item.expanded) {
                    item.expanded = true
                }
                // where to insert 示例添加到尾部，可以是随意位置
                item.children.push(dragObj)
            })
        }else if(type === '3'){
            let ar
            let i
            let key=dragObj.key
            loop(data, key, (item, index, arr) => {
                ar = arr
                i = index
            })
            ar.splice(i, 1, dragObj)
        }else if(type === '4'){
            if(!dragKey){
                dragKey=dragObj.key
            }
            loop(data, dragKey, (item, index, arr) => {
              arr.splice(index, 1)
            })
            this.theSelectedKeys = []
        }
        if(type === '1'||type === '2'||type === '3'){
            this.treeList = data
            const newSelect = []
            newSelect.push(dragObj.key)
            this.theSelectedKeys = newSelect
        }
        if(type === '1'||type === '2'){
            const newExpandedKeys = this.theExpandedKeys
            if (newExpandedKeys && newExpandedKeys.length > 0) {
                if (newExpandedKeys.indexOf(dropKey) <= 0) {
                    newExpandedKeys.push(dropKey)
                    this.theExpandedKeys = newExpandedKeys
                }
            }
        }
    }
        
  }
}
</script>